package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.bean.BeanException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.utils.DateTimeZoneConverter;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.domain.DeviceDataHistory;
import com.zzyl.nursing.mapper.DeviceDataHistoryMapper;
import com.zzyl.nursing.mapper.DeviceMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.service.IDeviceDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Set;

/**
 * 设备数据Service业务层处理
 * 
 * @author zqz
 * @date 2025-10-19
 */
@Service
public class DeviceDataServiceImpl extends ServiceImpl<DeviceDataMapper,DeviceData> implements IDeviceDataService
{
    @Autowired
    private DeviceDataMapper deviceDataMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private DeviceDataHistoryMapper deviceDataHistoryMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * 查询设备数据
     * 
     * @param id 设备数据主键
     * @return 设备数据
     */
    @Override
    public DeviceData selectDeviceDataById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询设备数据列表
     * 
     * @param deviceData 设备数据
     * @return 设备数据
     */
    @Override
    public List<DeviceData> selectDeviceDataList(DeviceData deviceData)
    {
        return deviceDataMapper.selectDeviceDataList(deviceData);
    }

    /**
     * 新增设备数据
     * 
     * @param deviceData 设备数据
     * @return 结果
     */
    @Override
    public int insertDeviceData(DeviceData deviceData)
    {
        return save(deviceData)?1:0;
    }

    /**
     * 修改设备数据
     * 
     * @param deviceData 设备数据
     * @return 结果
     */
    @Override
    public int updateDeviceData(DeviceData deviceData)
    {
        return updateById(deviceData)?1:0;
    }

    /**
     * 批量删除设备数据
     * 
     * @param ids 需要删除的设备数据主键
     * @return 结果
     */
    @Override
    public int deleteDeviceDataByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids))?1:0;
    }

    /**
     * 删除设备数据信息
     * 
     * @param id 设备数据主键
     * @return 结果
     */
    @Override
    public int deleteDeviceDataById(Long id)
    {
        return removeById(id)?1:0;
    }

    /**
     * 批量新增上报的数据
     *
     * @param contentStr
     */
    @Override
    public void batchDeviceDataByContentStr(String contentStr) {
        if (StringUtils.isEmpty(contentStr)){
            return;
        }
        JSONObject jsonObject = JSONUtil.parseObj(contentStr);
        // 1.从contentStr获取对象
        JSONObject properties  = (JSONObject)jsonObject.getByPath("notify_data.body.services[0].properties");
        // 2.从contentStr获取设备id
        String iotId = jsonObject.getByPath("notify_data.header.device_id",String.class);
        // 3.从contentStr获取时间
        String eventTimeStr = jsonObject.get("event_time",String.class);
        LocalDateTime parse = LocalDateTimeUtil.parse(eventTimeStr, "yyyyMMdd'T'HHmmss'Z'");
        LocalDateTime eventTime = DateTimeZoneConverter.utcToShanghai(parse);
        // 3. 根据设备id获取设备对象
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getIotId,iotId);
        Device device = deviceMapper.selectOne(queryWrapper);
        if (device==null){
            return;
        }
        // 3. 创建一个集合
        List<DeviceData> deviceList = new ArrayList<>();
        // 4. 从properties获取keys集合并完成给
        Set<String> keys = properties.keySet();
        for (String key : keys) {
            Object value = properties.get(key);
            DeviceData deviceData = BeanUtil.toBean(device, DeviceData.class);
            // 不能用device的id
            deviceData.setId(null);
            deviceData.setAccessLocation(device.getBindingLocation());
            deviceData.setFunctionId(key);
            deviceData.setDataValue(value+"");
            deviceData.setAlarmTime(eventTime);
            // 把设备数据放到集合里面
            deviceList.add(deviceData);
        }
        // 将设备数据放到redis缓存中
        redisTemplate.boundHashOps(CacheConstants.IOT_DEVICE_LAST_DATA).put(iotId,JSONUtil.toJsonStr(deviceList));
        // 将设备数据放到数据库中
        this.saveBatch(deviceList);
    }

    /**
     * 历史表新增上报数据--不在内存保存数据
     */
    @Override
    public void insertDeviceDataHistory(Integer minute) {
        // 1.查询10分钟前最后一个设备id
        Long id =  deviceDataMapper.getLastId(minute);
        // 2.新增数据到历史表
        deviceDataMapper.insertData(id);
        // 3.删除原表数据
        deviceDataMapper.removeData(id);
    }

    /**
     * 历史表新增上报数据--内存保存数据
     */
/*    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertDeviceDataHistory() {
        // 1.查询10分钟前的数据
        // 获取十分钟前的时间
        LocalDateTime localDateTimeLast = LocalDateTime.now().minusMinutes(10);
        LambdaQueryWrapper<DeviceData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.lt(DeviceData::getAlarmTime,localDateTimeLast);
        List<DeviceData> dataList = this.list(queryWrapper);
        if (dataList == null){
            throw new BeanException("没有十分钟之前的数据");
        }
        // 获取集合的长度
        int size = dataList.size();
        // 获取最后一个id
        Long id = dataList.get(size - 1).getId();
        // 2.数据新增到一个表中
        for (DeviceData deviceData : dataList) {
            DeviceDataHistory deviceDataHistory = BeanUtil.toBean(deviceData, DeviceDataHistory.class);
            deviceDataHistoryMapper.insert(deviceDataHistory);
        }
        // 3.删除原表中数据
        // 删除从id之前的数据
        LambdaQueryWrapper<DeviceData> deleteQuery = new LambdaQueryWrapper<>();
        deleteQuery.le(DeviceData::getId,id);
        deleteQuery.lt(DeviceData::getAlarmTime,localDateTimeLast);
        this.remove(deleteQuery);
    }*/

}
